using UnityEngine;
using System;
using System.Collections;

public class Jogador : MonoBehaviour
{

		// movement config
		/*
		public float gravity = -25f;
		public float runSpeed = 8f;
		public float groundDamping = 20f; // how fast do we change direction? higher means faster
		public float inAirDamping = 5f;
		public float jumpHeight = 3f;
	 */
		//control
		public float gravity = -500;
		public float maxWalkSpeed = 100;
		public float groundDamping = 3; // how fast do we change direction? higher means faster
		public float inAirDamping = 1;
		public float jumpHeight = 60;
		public float aceleracao = 1;
		private bool facingRight = true;
		private int itemQtd = 0;
		public bool vivo = true;
		public bool stunado = false;

		//action
		public GameObject stoneShot;
		public float shotSpeed;
		public float shootCooldown;
		public Cooldown cd_fumaca_andar = new Cooldown (1);
		public Cooldown cd_testaMorte = new Cooldown (1);
		public Cooldown cd_porrada = new Cooldown (1);
		[HideInInspector]
		private float
		normalizedHorizontalSpeed = 0;
		private CharacterController2D _controller;
		private Animator _animator;
		private RaycastHit2D _lastControllerColliderHit;
		private Vector3 _velocity;
		private float runSpeed;
		private int jumpLimit = 2;
		private int jumpCount;
		public KeySet teclas;
		public float speeds = 6.0F;
		private Vector3 moveDirection = Vector3.zero;
		public Hud HUDGame;

		//boost
		public int atkBoost = 0;
		public int lifeBoost = 0;
		public int defBoost = 0;


		// listen to some events for illustration purposes
		/*_controller.onControllerCollidedEvent += onControllerCollider;
		_controller.onTriggerEnterEvent += onTriggerEnterEvent;
		_controller.onTriggerExitEvent += onTriggerExitEvent;*/
		

		public void OnTrigger (Collision col)
		{
				Debug.Log ("COLIDI COM " + col.gameObject.name);
		}

		public void testaColisoesTosco ()
		{
				if (!cd_porrada.jaAcabou ()) {
						return;
				}
				if (stunado)
						return;
				cd_porrada = new Cooldown (5);
				foreach (GameObject jogador in GameController.jogadores) {
						if (jogador == null)
								continue;
						if (this.gameObject == jogador)
								continue;
						Bounds meu = this.gameObject.renderer.bounds;
						Bounds inimigo = jogador.renderer.bounds;
						if (meu.Intersects (inimigo)) {
								GameObject quemTomo = this.gameObject;
								Jogador jog = jogador.GetComponent<Jogador> ();
								
								GameObject esquerda = null;
								GameObject direita = null;
								if (this.gameObject.transform.position.x < jogador.transform.position.x) {
										esquerda = this.gameObject;
										direita = jogador;
								} else {
										esquerda = jogador;
										direita = this.gameObject;
								}

								//if(jogador.

								jog = esquerda.GetComponent<Jogador> ();
								Jogador jog2 = direita.GetComponent<Jogador> ();

								Vector3 velocidadeBatida = jog._velocity + jog2._velocity;
								//Debug.Log ("BATI COM VELOCIDADE " + velocidadeBatida.ToString ());

								//Debug.Log ("Caller: " + this.gameObject.name + " Esquerda :" + esquerda.name + " Direita: " + direita.name);

								if (esquerda.name == this.name) {
										velocidadeBatida *= -1;
								}
								velocidadeBatida *= -1;
								velocidadeBatida.y = 0;
								

								float meuY = jogador.transform.position.y;
								float seuY = this.gameObject.transform.position.y;
								
								GameObject pisou = null;
								GameObject pisado = null;

								if (seuY - meuY > 5) {
									pisado = jogador;
									pisou = this.gameObject;
								} else if (meuY - seuY > 5) {
									
										pisado = this.gameObject;
										pisou = jogador;
								}

								if (pisou != null) {
										Jogador quePisou = pisou.GetComponent<Jogador> ();
										Jogador queTomou = pisado.GetComponent<Jogador> ();
										queTomou.stunado = true;
										
										queTomou.timerTiraStun (0.1f);
										quePisou.stunado = true;
										
										quePisou.timerTiraStun (0.1f);
										queTomou._velocity.y = -100;
										quePisou._velocity.y = 150;
										//quePisou.stunado = true;
										//quePisou.timerTiraStun (0.1f);
										quePisou._animator.Play (Animator.StringToHash ("Jump"));
										//quePisou.stunado = true;
										//quepisou.timerTiraStun(0.1f);
										
										GameController.playHit (jogador.transform.position, this.gameObject.transform.position);

								} else {
					                    Debug.Log ("X1 "+jog._velocity.x+" X2 "+jog2._velocity.x);
										if(jog._velocity.x !=0 || jog2._velocity.x !=0) {
											// stun inimigo
											jog.stunado = true;
											jog.timerTiraStun (0.1f);
											jog._velocity -= velocidadeBatida*1.2f;
											// meu stun
											jog2.stunado = true;
											jog2.timerTiraStun (0.1f);
						jog2._velocity += velocidadeBatida*1.2f;
											GameController.playHit (jogador.transform.position, this.gameObject.transform.position);
										}
										
								}
								

						}
				}
		}

		public void timerTiraStun (float tempo)
		{
				Invoke ("tiraStun", 0.6f);

		}

		private void tiraStun ()
		{
				stunado = false;
				Debug.Log ("Tirei o stun");
		}

	
	void Awake()
	{
		_animator = GetComponent<Animator>();
		_controller = GetComponent<CharacterController2D>();

		//hud
		HUDGame = Camera.main.GetComponent<Hud>();

	}
	
	
	#region Event Listeners

		public CharacterController2D getController ()
		{
				return _controller;
		}

	#endregion
	
		private bool _up;
		private bool _right;
		private bool _left;
		private bool _actionBtn;
		private bool _down;


		// the Update loop only gathers input. Actual movement is handled in FixedUpdate because we are using the Physics system for movement
		void Update ()
		{
				// a minor bit of trickery here. FixedUpdate sets _up to false so to ensure we never miss any jump presses we leave _up
				// set to true if it was true the previous frame
				_up = teclas.pertouCima ();
				_down = teclas.pertouBaixo ();
				_right = teclas.pertouDireita ();
				_left = teclas.pertouEsquerda ();
				_actionBtn = teclas.pertouAcao ();

				if (teclas.apertouPause ()) {
						Time.timeScale = 0;
						MenuPause.guiShowElements = true;
				} 

				if (shootCooldown > 0)
				{
					shootCooldown -= Time.deltaTime;
				}

				if(this.vivo == false){
					Color originalColour = this.renderer.material.color;
					float newAlpha = 0.0f;
					this.renderer.material.color = new Color(originalColour.r, originalColour.g, originalColour.b, newAlpha);
					GameObject penultimo = GameController.getPenultimoVivoNaCorrida (this.gameObject);
					this.transform.position = new Vector3(penultimo.transform.position.x - 10,penultimo.transform.position.y + 5, 0);
					_animator.Play(Animator.StringToHash("Ghost"));
					//
				}
		}

	public void morreNeguim() {
		//this.vivo = false;
		GameObject ultimo = GameController.getUltimoVivoNaCorrida();
		// PAREI AKI CARAIH
		Debug.Log (this.gameObject.name);
		switch (this.gameObject.name) {
			case "Jogador(Clone)":
				if(HUDGame.playerOneLife == 0){
					this.vivo = false;
					//Destroy(this.gameObject);
				}else{
					HUDGame.playerOneLife--;
					this.Respawn(ultimo);
				}
				break;
			case "Jogador2(Clone)":
				if(HUDGame.playerTwoLife == 0){
					this.vivo = false;
					//Destroy(this.gameObject);
				}else{
					HUDGame.playerTwoLife--;
					this.Respawn(ultimo);
				}
				break;
			case "Jogador3(Clone)":
				if(HUDGame.playerThreeLife == 0){
					this.vivo = false;
					//Destroy(this.gameObject);
				}else{
					HUDGame.playerThreeLife--;
					this.Respawn(ultimo);
				}
				break;
			case "Jogador4(Clone)":
				if(HUDGame.playerFourLife == 0){
					this.vivo = false;
					//Destroy(this.gameObject);
				}else{
					HUDGame.playerFourLife--;
					this.Respawn(ultimo);
				}
				break;
		}

	}

	void FixedUpdate ()
	{

		if (!cd_testaMorte.jaAcabou ()) {
				cd_testaMorte = new Cooldown (1);
				GameObject primeiro = GameController.getPrimeiroNaCorrida ();
				if (primeiro != this) {
						float diferenca = primeiro.transform.position.x - transform.position.x;
						if (diferenca > 500) {
								morreNeguim ();
						}
				}
		}

		if (this.stunado) {
				_animator.Play (Animator.StringToHash ("DoubleJump"));
		} else {
				// grab our current _velocity to use as a base for all calculations
				_velocity = _controller.velocity;
				//Debug.Log ("GROUND:"+_controller.isGrounded, this);
	
				if (_controller.isGrounded == true) {
						jumpCount = 0;
				}
	
				if (_right) {
						facingRight = true;
						normalizedHorizontalSpeed = 1;
						if (transform.localScale.x > 0f)
								transform.localScale = new Vector3 (-transform.localScale.x, transform.localScale.y, transform.localScale.z);
						if (_controller.isGrounded == true) {
								if (Math.Abs (_velocity.x) > maxWalkSpeed / 1.2) {
										if (cd_fumaca_andar.jaAcabou ()) {
												cd_fumaca_andar = new Cooldown (100);
												GameController.playSmoke (transform.position.x, transform.position.y - 5.5f, transform.position.z);
										}
										_animator.Play (Animator.StringToHash ("Run"));
								} else {
										_animator.Play (Animator.StringToHash ("Walk"));
								}
								runSpeed = maxWalkSpeed;
						}
				} else if (_left) {
						facingRight = false;
						normalizedHorizontalSpeed = -1;
						if (transform.localScale.x < 0f)
								transform.localScale = new Vector3 (-transform.localScale.x, transform.localScale.y, transform.localScale.z);
						if (_controller.isGrounded == true) {			
								if (Math.Abs (_velocity.x) > maxWalkSpeed / 1.2) {
										if (cd_fumaca_andar.jaAcabou ()) {
												cd_fumaca_andar = new Cooldown (100);
												GameController.playSmoke (transform.position.x, transform.position.y - 5.5f, transform.position.z);
										}
										_animator.Play (Animator.StringToHash ("Run"));
								} else {
										_animator.Play (Animator.StringToHash ("Walk"));
								}
								runSpeed = maxWalkSpeed;
			
						}
				} else if (!_up) {
						normalizedHorizontalSpeed = 0;
						if (_controller.isGrounded == true) {
								//_animator.animation.CrossFadeQueued("Iddle", 0.3f, QueueMode.CompleteOthers);
								_animator.Play (Animator.StringToHash ("Iddle"));
								_up = teclas.parado ();
								_down = teclas.parado ();
								_right = teclas.parado ();
								_left = teclas.parado ();
			
						}
		
				} 
				//Shoot
				if (_actionBtn) {
						Shoot ();
				}
	
				//double jump
				if (_controller.isGrounded == false) {
						if (_up) {
								//jumpCount++;
								if (jumpCount == 2) {
										_velocity.y = Mathf.Sqrt (2f * jumpHeight * -gravity);
										_animator.Play (Animator.StringToHash ("DoubleJump"));
										jumpCount = 3;
										GameController.playSmoke (transform.position.x, transform.position.y - 1.5f, transform.position.z);
								}
						}
				} 
	
				// we can only jump whilst grounded
				else if (_controller.isGrounded == true && _up) {
						_velocity.y = Mathf.Sqrt (2f * jumpHeight * -gravity);
						_animator.Play (Animator.StringToHash ("Jump"));
						jumpCount = 1;
						GameController.playSmoke (transform.position.x, transform.position.y - 5.5f, transform.position.z);
				}
				if (teclas.desapertouCima ()) {
						if (jumpCount == 1) {
								jumpCount = 2;
						}
				}
	
				//caiu, morreu
				if (_velocity.y < 1 && !_controller.isGrounded) {
						//_animator.animation.CrossFadeQueued("Fall",0.3f,QueueMode.CompleteOthers);
						_animator.Play (Animator.StringToHash ("Fall"));
						if (_velocity.y < -515) {
								this.morreNeguim ();
						}
				}

				// apply horizontal speed smoothing it
				var smoothedMovementFactor = _controller.isGrounded ? groundDamping : inAirDamping; // how fast do we change direction?
				_velocity.x = Mathf.Lerp (_velocity.x, normalizedHorizontalSpeed * runSpeed, Time.fixedDeltaTime * smoothedMovementFactor);
	
				// apply gravity before moving
				_velocity.y += gravity * Time.fixedDeltaTime;
	
				_controller.move (_velocity * Time.fixedDeltaTime);
				testaColisoesTosco ();
				// reset input
				//_up = false;
		
			}
	}
	    void Respawn(GameObject Ultimo)
	    {
			//GameObject spawn = GameObject.Find ("SpawnPoint");
			if (this.gameObject.name == Ultimo.name) {
				GameObject penultimo = GameController.getPenultimoVivoNaCorrida (this.gameObject);
				transform.position = new Vector3 (penultimo.transform.position.x - 5, penultimo.transform.position.y + 3, 0);
			} else {
					transform.position = new Vector3 (Ultimo.transform.position.x - 5, Ultimo.transform.position.y + 3, 0);
			}
	    } 

		void Shoot ()
		{
				//if(CoolDown() == true){
				_animator.Play (Animator.StringToHash ("Shoot"));
				GameObject bullet = (GameObject)Instantiate (stoneShot, transform.position, transform.rotation);

				if (facingRight == true) {
						bullet.rigidbody2D.AddForce (Vector2.right * shotSpeed);
				} else {
						bullet.rigidbody2D.AddForce (-Vector2.right * shotSpeed);
				}
            
				//shootCooldown = 0.4f;
				//}
		}

		bool CoolDown ()
		{
				if (shootCooldown > 0) {
						return false;
				} else {
						return true;
				}
        
		}

		public void setBoost(string type){

			switch (type) {
				case "atk":
					atkBoost++;
					break;
				case "life":
					lifeBoost++;
					break;
				case "def":
					defBoost++;
					break;

			}

			switch (this.gameObject.name) {
			case "Jogador(Clone)":
				if(HUDGame.playerOneLife < 5 ){
					HUDGame.playerOneLife++;
				}
				break;
			case "Jogador2(Clone)":
				if(HUDGame.playerTwoLife < 5 ){
					HUDGame.playerTwoLife++;
				}
				break;
			case "Jogador3(Clone)":
				if(HUDGame.playerThreeLife < 5 ){
					HUDGame.playerThreeLife++;
				}
				break;
			case "Jogador4(Clone)":
				if(HUDGame.playerFourLife < 5 ){
					HUDGame.playerFourLife++;
				}
				break;
			}
		Debug.Log ("setei o type:"+type);

	}
	
}

